package com.crawler.waf.config;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.context.SecurityContextPersistenceFilter;

import com.crawler.waf.filter.TokenAuthenticationProcessFilter;
import com.crawler.waf.security.authentication.PreAuthenticatedAuthenticationExtractorManager;

public abstract class AbstractWebSecurityConfigurerAdapter extends  WebSecurityConfigurerAdapter {

    @Autowired
    private PreAuthenticatedAuthenticationExtractorManager extractorManager;

    protected AbstractWebSecurityConfigurerAdapter() {
        super(true);
    }


    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth,List<AuthenticationProvider> providers)
            throws Exception {

        for (AuthenticationProvider provider : providers)
            auth.authenticationProvider(provider);
    }

    /**
     * 配置安全请求路径和角色的匹配，并且定制安全所需要的过滤器为5个
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // session的创建策略采用无状态创建策略
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .securityContext()
                .and()
                .addFilterAfter(tokenAuthenticationProcessFilter(),
                        SecurityContextPersistenceFilter.class).anonymous()
                .and();

         this.onConfigure(http);
    }

    /**
     * 扩展spring security的授权路径配置
     *
     * @param http
     * @throws Exception
     */
    protected abstract void onConfigure(HttpSecurity http) throws Exception;


    /**
     * 构建一个token的过滤器，此过滤器的主要目的是从请求头信息中获得token字符串信息
     *
     * @return
     * @throws Exception
     */
    protected TokenAuthenticationProcessFilter tokenAuthenticationProcessFilter()
            throws Exception {
        TokenAuthenticationProcessFilter filter = new TokenAuthenticationProcessFilter(
                super.authenticationManager(),extractorManager);
        return filter;
    }

    /**
     * 默认实现，当前的应用是不需要安全认证的。在需要安全认证的时候，重写此方法。
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/**");
    }
}
